package dao

import (
	"context"
	"sale-admin/config/mysql"
	"sale-admin/internal/dal"
	"sale-admin/internal/models"
	"strings"
	"time"

	sharding "192.168.1.75/go-pkg/db-sharding"
	"192.168.1.75/go-pkg/helper"
	"github.com/golang-module/carbon/v2"
)

type StareCount struct{}

func (StareCount) Save(ctx context.Context, query *dal.Query, merchantID, robotName string,
	startTime, endTime, stareCount, stareCount0, stareCount1, stareCount2, stareCount3, locationID int64) (err error) {
	m := query.StareCount
	dbs := sharding.GetDB(ctx, mysql.NewDB(), m.TableName(), startTime, startTime)
	queryDBTx := dal.Use(dbs.QueryDB).StareCount.WithContext(ctx)
	writeDBTx := dal.Use(dbs.WriteDB).StareCount.WithContext(ctx)
	updateDBTx := dal.Use(dbs.UpdateDB).StareCount.WithContext(ctx)

	var data models.StareCount
	data.MerchantID = merchantID
	data.RobotName = robotName
	data.StartTime = startTime
	data.EndTime = endTime
	data.StareCount0 = stareCount0
	data.StareCount1 = stareCount1
	data.StareCount2 = stareCount2
	data.StareCount3 = stareCount3
	data.LocationID = locationID
	data.CreatedAt = time.Now().Unix()
	data.CreatedDate = carbon.Now().ToDateString()

	count, _ := queryDBTx.Where(
		m.RobotName.Eq(robotName),
		m.StartTime.Eq(startTime),
		m.EndTime.Eq(endTime),
	).Count()
	// 新增
	if count <= 0 {
		data.ID, _ = helper.UUID{}.String()
		writeDBTx.Create(&data)
	} else {
		// 更新数据
		updateDBTx.Where(
			m.RobotName.Eq(robotName),
			m.StartTime.Eq(startTime),
			m.EndTime.Eq(endTime),
		).Updates(&data)
	}
	return
}

type StareCountList struct {
	RobotName   string `json:"robot_name"`
	CreatedDate string `json:"created_date"`
	StareCount  int64  `json:"stare_count"`
	StareCount0 int64  `json:"stare_count0"`
	StareCount1 int64  `json:"stare_count1"`
	StareCount2 int64  `json:"stare_count2"`
	StareCount3 int64  `json:"stare_count3"`
}

// 总计
func (StareCount) Total(ctx context.Context, query *dal.Query, merchantID, robotName string,
	startTime, endTime int64) (total StareCountList) {
	m := query.StareCount
	dbs := sharding.GetDB(ctx, mysql.NewDB(), m.TableName(), startTime, startTime)
	start := carbon.CreateFromTimestamp(startTime).ToDateString()
	end := carbon.CreateFromTimestamp(endTime).ToDateString()
	tx := dal.Use(dbs.QueryDB).StareCount.
		WithContext(ctx).
		Where(m.CreatedDate.Between(start, end))
	if merchantID != "" {
		tx = tx.Where(m.MerchantID.In(strings.Split(merchantID, ",")...))
	}
	if robotName != "" {
		tx = tx.Where(m.RobotName.In(strings.Split(robotName, ",")...))
	}
	tx.Select(
		m.StareCount0.Sum().As(m.StareCount0.ColumnName().String()),
		m.StareCount1.Sum().As(m.StareCount1.ColumnName().String()),
		m.StareCount2.Sum().As(m.StareCount2.ColumnName().String()),
		m.StareCount3.Sum().As(m.StareCount3.ColumnName().String()),
	).
		Scan(&total)
	total.StareCount = total.StareCount0 + total.StareCount1 + total.StareCount2 + total.StareCount3
	return
}

// 日期+机器 分组后的凝视数据列表
func (StareCount) List(ctx context.Context, query *dal.Query, merchantID, robotName string,
	startTime, endTime int64, page, limit int) (res []StareCountList) {
	m := query.StareCount
	dbs := sharding.GetDB(ctx, mysql.NewDB(), m.TableName(), startTime, startTime)
	start := carbon.CreateFromTimestamp(startTime).ToDateString()
	end := carbon.CreateFromTimestamp(endTime).ToDateString()
	tx := dal.Use(dbs.QueryDB).StareCount.
		WithContext(ctx).
		Where(m.CreatedDate.Between(start, end))
	if merchantID != "" {
		tx = tx.Where(m.MerchantID.In(strings.Split(merchantID, ",")...))
	}
	if robotName != "" {
		tx = tx.Where(m.RobotName.In(strings.Split(robotName, ",")...))
	}

	// 机器 + 日期 分组
	offset, limit := Offset(page, limit)
	tx.Group(m.CreatedDate, m.RobotName).
		Select(m.RobotName, m.CreatedDate,
			m.StareCount0.Sum().As(m.StareCount0.ColumnName().String()),
			m.StareCount1.Sum().As(m.StareCount1.ColumnName().String()),
			m.StareCount2.Sum().As(m.StareCount2.ColumnName().String()),
			m.StareCount3.Sum().As(m.StareCount3.ColumnName().String()),
		).
		ScanByPage(&res, offset, limit)
	for k, v := range res {
		res[k].StareCount = v.StareCount0 + v.StareCount1 + v.StareCount2 + v.StareCount3
	}
	return res
}

// 获取机器单日凝视
func (StareCount) GetDailyStareCount(ctx context.Context, query *dal.Query, robotName, date string) (
	res StareCountList,
) {
	if robotName == "" || date == "" {
		return
	}
	m := query.StareCount
	dbs := sharding.GetDB(ctx, mysql.NewDB(), m.TableName(),
		carbon.Parse(date).Timestamp(),
		carbon.Parse(date).Timestamp(),
	)
	dal.Use(dbs.QueryDB).StareCount.
		WithContext(ctx).
		Where(m.RobotName.Eq(robotName)).
		Where(m.CreatedDate.Eq(date)).
		Select(
			m.StareCount0.Sum().As(m.StareCount0.ColumnName().String()),
			m.StareCount1.Sum().As(m.StareCount1.ColumnName().String()),
			m.StareCount2.Sum().As(m.StareCount2.ColumnName().String()),
			m.StareCount3.Sum().As(m.StareCount3.ColumnName().String()),
		).Scan(&res)
	res.StareCount = res.StareCount0 + res.StareCount1 + res.StareCount2 + res.StareCount3
	return
}
